package auths

import (
	"context"
	"gitee.com/lailonghui/vehicle-supervision-framework/pkg/loggers"
	graphql "github.com/99designs/gqlgen/graphql"
	"github.com/gin-gonic/gin"
	"github.com/spf13/viper"
	"github.com/vektah/gqlparser/v2/gqlerror"
	"go.uber.org/zap"
)

type GinContextExtract func(c context.Context) (*gin.Context, error)

func GqlgenRbacAuthMiddle(viper *viper.Viper, GinContextExtract GinContextExtract, ignoreMethods ...string) graphql.ResponseMiddleware {
	return func(ctx context.Context, next graphql.ResponseHandler) *graphql.Response {
		/*operationContext := graphql.GetOperationContext(ctx)
		operationDefinition := operationContext.Doc.Operations.ForName(operationContext.OperationName)*/
		authType := viper.GetString("auth.type")
		publicKey := viper.GetString("rbac.publicKey")
		c, err := GinContextExtract(ctx)
		if err != nil {
			loggers.Error("提取上下文异常", ctx, zap.Error(err))
			c.Status(401)
			return gqlgenNotAuthResponse()
		}
		if authType == AUTH_TYPE_SERVER {
			authAddress := viper.GetString("auth.address")
			valid := serverAuthValid(c, authAddress)
			if !valid {
				loggers.Error("权限服务验证token无效", ctx, zap.Error(err))
				c.Status(401)
				return gqlgenNotAuthResponse()
			}
		}
		tokenValue := getToken(c)
		if tokenValue != "" {
			newCtx, err := NewCtxWithRbacAuth(publicKey, tokenValue, ctx)
			if err != nil {
				c.Status(401)
				return gqlgenNotAuthResponse()
			}
			c.Request = c.Request.WithContext(newCtx)
			ctx = newCtx
		}
		response := next(ctx)
		return response
	}

}

func gqlgenNotAuthResponse() *graphql.Response {
	notAuthGqlerror := &gqlerror.Error{
		Message: "NOT AUTH",
	}
	return &graphql.Response{
		Errors: []*gqlerror.Error{notAuthGqlerror},
	}

}
